package bot.controller;

import bot.conf.MpperUnit;
import bot.mapper.*;
import bot.pojo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * rpg小游戏
 * */
@RestController
@RequestMapping("/RPG")
public class RpgController {
    //TODO : 目前有打成jar包后bean初始化异常的问题，idea启动项目正常
    /**
     * @查看玩家信息接口，若数据库无该qq号玩家则自动创建，若有查看有无当前这个玩家的对局
     * 上个对局未结束时将继续战斗
     * */
    private PropTableExample propTableExample = new PropTableExample();
    private PropToUserExample propToUserExample = new PropToUserExample();
    private CharacterToUserMapper characterToUserMapper = MpperUnit.staticmpperUnit.getCharacterToUserMapper();
    private GameUserTableMapper gameUserTableMapper = MpperUnit.staticmpperUnit.getGameUserTableMapper();
    private GameTableMapper gameTableMapper = MpperUnit.staticmpperUnit.getGameTableMapper();
    private GameTableExample gameTableExample = new GameTableExample();
    private GameUserTableExample gameUserTableExample = new GameUserTableExample();
    private CharacterToUserExample characterToUserExample = new CharacterToUserExample();

    private PropTableMapper propTableMapper = MpperUnit.staticmpperUnit.getPropTableMapper();
    private PropToUserMapper propToUserMapper = MpperUnit.staticmpperUnit.getPropToUserMapper();

    private CharacterTableExample characterTableExample = new CharacterTableExample();
    private CharacterTableMapper characterTableMapper = MpperUnit.staticmpperUnit.getCharacterTableMapper();
    private List<PropTable> list = MpperUnit.staticmpperUnit.getPropTableList();
    private EnemyTableMapper enemyTableMapper = MpperUnit.staticmpperUnit.getEnemyTableMapper();
    private List<EnemyTable> enemyTables = MpperUnit.staticmpperUnit.getEnemyTables();
   static List<Integer> deff = new ArrayList<>();
   static {
       deff.add(1);
       deff.add(2);
       deff.add(3);

   }
    @GetMapping("/getGameUser")
    public Object getGameUser (String qqid){
        gameUserTableExample.clear();
        GameUserTableExample.Criteria criteria = gameUserTableExample.createCriteria();
        criteria.andQqIdEqualTo(qqid);
        List<GameUserTable> gameUserTables = gameUserTableMapper.selectByExample(gameUserTableExample);
        if(gameUserTables.size() == 0){
            GameUserTable gameUserTable = new GameUserTable();
            gameUserTable.setQqId(qqid);
            gameUserTable.setCreateTime(new SimpleDateFormat("YYYY-MM-dd HH:mm").format(new Date()));
            gameUserTable.setCharacterCard1(deff.get(0));//初始角色卡1 id = 1
            gameUserTable.setCharacterCard2(deff.get(1));//初始角色卡3 id = 2
            gameUserTable.setCharacterCard3(deff.get(2));//初始角色卡2 id = 3
            int insert = gameUserTableMapper.insert(gameUserTable);
            //角色卡绑定玩家
            //初始卡三张
            for(Integer id : deff){
                CharacterToUser characterToUser = new CharacterToUser();
                characterToUser.setQqId(qqid);
                characterToUser.setGameUserId(insert);
                characterToUser.setCreateTime(new SimpleDateFormat("YYYY-MM-dd HH:mm").format(new Date()));
                characterToUser.setCharacterId(id);
                characterToUserMapper.insert(characterToUser);
            }
            //角色创建，创建游戏
            return "ok";
        }
        else{
            //查找这个玩家有没有正在进行的战斗
            gameTableExample.clear();
            gameTableExample.createCriteria().andQqIdEqualTo(qqid).andGameStatusEqualTo(1);
            if(gameTableMapper.countByExample(gameTableExample) > 0){
                return "err";
            }

            GameUserTable gameUserTable = gameUserTables.get(0);
            //随机事件1，获取随机道具/资源。2，遇见战斗
            String s = ShiJian();
            if(s != null){
                switch (s){
                    case "get":
                        System.out.println("获取资源");
                        //从道具列表随机获取一个
                        int index = new Random().nextInt(list.size());
                        //未来给道具加权重
                        PropTable propTable = list.get(index);
                        //查看玩家是否有这个道具，如果有只新增剩余道具数量，否则添加一个对象
                        propToUserExample.clear();
                        propToUserExample.createCriteria().andQqIdEqualTo(qqid).andPropIdEqualTo(propTable.getId());
                        List<PropToUser> propToUsers = propToUserMapper.selectByExample(propToUserExample);
                        if(propToUsers.size() != 0){
                            PropToUser propToUser = propToUsers.get(0);
                            propToUser.setCount(propToUser.getCount() + 1);
                            propToUserMapper.updateByPrimaryKeySelective(propToUser);
                            return JsonReturn.ok(propTable.getName() +"数量+1，剩余"+propToUser.getCount());
                        }else {
                            PropToUser propToUser = new PropToUser();
                            propToUser.setCount(1);
                            propToUser.setQqId(qqid);
                            propToUser.setUserId(gameUserTable.getId());
                            propToUser.setPropId(propTable.getId());
                            propToUserMapper.insert(propToUser);
                            return JsonReturn.ok("新增道具:"+propTable.getName());

                        }
                    case "fight":
                        StringBuffer stringBuffer = new StringBuffer();
                        stringBuffer.append("遇见敌人!" + "\n");
                        System.out.println("战斗");
                        //查找和这个玩家等级不超过10的敌人
                        List<EnemyTable> collect = enemyTables.stream().filter(data -> {
                                    if ((data.getLv() - gameUserTable.getGrade()) < 10) {
                                        return true;
                                    }
                                    return false;
                                }
                        ).collect(Collectors.toList());
                        int random = new Random().nextInt(collect.size());
                        EnemyTable enemyTable = collect.get(random);

                        //获取角色卡组等级

                        //System.out.println("遇见敌人"+ enemyTable.getName());
                        //创建战斗对象
                        GameTable gameTable = new GameTable();
                        gameTable.setUserTableId(gameUserTable.getId());
                        gameTable.setQqId(qqid);
                        gameTable.setGameStatus(1);//初始状态
                        gameTable.setCreateTime(new SimpleDateFormat("YYYY-MM-dd HH:ss").format(new Date()));
                        //获取用户的角色卡组并作为对局携带的
                        gameTable.setCharacterCard1(gameUserTable.getCharacterCard1());
                        gameTable.setCharacterCard2(gameUserTable.getCharacterCard2());
                        gameTable.setCharacterCard3(gameUserTable.getCharacterCard3());
                        //记录每个角色的血量信息
                        if(gameTable.getCharacterCard1() != null){
                            gameTable.setNowCard(gameTable.getCharacterCard1());//默认第一个出站的角色
                            CharacterTable characterTable = characterTableMapper.selectByPrimaryKey(gameTable.getCharacterCard1());
                            stringBuffer.append("我方角色卡:" + "\n");
                            stringBuffer.append(characterTable.getName()  + "\n");

                            //根据玩家拥有的这个角色等级追加属性
                            characterToUserExample.clear();
                            characterToUserExample.createCriteria().andQqIdEqualTo(qqid).andCharacterIdEqualTo(gameTable.getCharacterCard1());
                            Integer lv = characterToUserMapper.selectByExample(characterToUserExample).get(0).getLv();
                            Integer integer = CharacterBool(Integer.valueOf(characterTable.getHp()), lv);

                            stringBuffer.append("血量:" + integer);
                            stringBuffer.append(blood(Integer.valueOf(characterTable.getHp()) , Integer.valueOf(characterTable.getHp())));
                            stringBuffer.append("\n");
                            gameTable.setCard1Hp(integer.toString());
                            gameTable.setCard1MaxHp(integer.toString());
                        }
                        if(gameTable.getCharacterCard2() != null){
                            CharacterTable characterTable = characterTableMapper.selectByPrimaryKey(gameTable.getCharacterCard2());

                            characterToUserExample.clear();
                            characterToUserExample.createCriteria().andQqIdEqualTo(qqid).andCharacterIdEqualTo(gameTable.getCharacterCard2());
                            Integer lv = characterToUserMapper.selectByExample(characterToUserExample).get(0).getLv();
                            Integer integer = CharacterBool(Integer.valueOf(characterTable.getHp()), lv);

                            gameTable.setCard2Hp(integer.toString());
                            gameTable.setCard2MaxHp(integer.toString());
                        }
                        if(gameTable.getCharacterCard3() != null){
                            CharacterTable characterTable = characterTableMapper.selectByPrimaryKey(gameTable.getCharacterCard3());

                            characterToUserExample.clear();
                            characterToUserExample.createCriteria().andQqIdEqualTo(qqid).andCharacterIdEqualTo(gameTable.getCharacterCard3());
                            Integer lv = characterToUserMapper.selectByExample(characterToUserExample).get(0).getLv();
                            Integer integer = CharacterBool(Integer.valueOf(characterTable.getHp()), lv);

                            gameTable.setCard3Hp(integer.toString());
                            gameTable.setCard3MaxHp(integer.toString());
                        }
                        //敌人信息
                        gameTable.setEnemyId(enemyTable.getId());
                        gameTable.setEnemyHp(enemyTable.getHp());
                        gameTable.setEnemyMaxHp(enemyTable.getHp());
                        stringBuffer.append("敌方信息:"  + "\n");
                        stringBuffer.append(enemyTable.getName());
                        stringBuffer.append("等级:"+enemyTable.getLv()  + "\n" );
                        stringBuffer.append("剩余血量:"+ enemyTable.getHp() + "\n");
                        stringBuffer.append(blood(Integer.valueOf(enemyTable.getHp()) , Integer.valueOf(enemyTable.getHp())));
                        //创建游戏
                        gameTableMapper.insert(gameTable);
                        //创建成功后构造字符串
                        System.out.println(stringBuffer);
                        return JsonReturn.ok(stringBuffer);
                    default:
                        return null ;
                    //...
                }
            }
            return null;
        }
    }
    //攻击
    @GetMapping("/gj")
    public JsonReturn gj(String qqid){
       //找到这个qq当前正在进行的对局
        gameTableExample.clear();
        gameTableExample.createCriteria().andQqIdEqualTo(qqid).andGameStatusEqualTo(1);
        List<GameTable> gameTables = gameTableMapper.selectByExample(gameTableExample);
        if(gameTables.size() == 0){
            return null;
        }
        GameTable gameTable = gameTables.get(0);
        //获取这个对局当前第一个角色的信息
        gameTable = AttackDamage(gameTable);
        //重新绘制血条
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("我方造成伤害:"+gameTable.getDamage() +"\\n");
        stringBuffer.append("敌方剩余血量:"+blood(Integer.valueOf(gameTable.getEnemyMaxHp()) , Integer.valueOf(gameTable.getEnemyHp()) ) +"\\n");
        stringBuffer.append("敌方对我放造成伤害:"+gameTable.getEDamage() +"\\n");
        //判断当前上场角色是第几位
        if(gameTable.getCharacterCard1() == gameTable.getNowCard()){
            stringBuffer.append("我方剩余血量:"+blood(Integer.valueOf(gameTable.getCard1MaxHp()) , Integer.valueOf(gameTable.getCard1Hp())) +"\\n");
        }
        if(gameTable.getCharacterCard2() == gameTable.getNowCard()){
            stringBuffer.append("我方剩余血量:"+blood(Integer.valueOf(gameTable.getCard2MaxHp()) , Integer.valueOf(gameTable.getCard2Hp())) +"\\n");
        }
        if(gameTable.getCharacterCard3() == gameTable.getNowCard()){
            stringBuffer.append("我方剩余血量:"+blood(Integer.valueOf(gameTable.getCard3MaxHp()) , Integer.valueOf(gameTable.getCard3Hp()) ) +"\\n");
        }
        //判断玩家/敌人血量是否归0
        if(gameTable.getWinName()!= null && !"".equals(gameTable.getWinName())){
            switch (gameTable.getWinName()){
                case "enemy" : //敌方胜利
                    stringBuffer.append(characterTableMapper.selectByPrimaryKey(gameTable.getNowCard()).getName()+"倒下了" + "\\n");
                    //校验是否还有存活角色，若全员死亡则游戏结束
                    if(Integer.valueOf(gameTable.getCard1Hp()) != 0){
                        stringBuffer.append("切换至:" + characterTableMapper.selectByPrimaryKey(gameTable.getCharacterCard1()).getName());
                        gameTable.setNowCard(gameTable.getCharacterCard1());
                        break;
                    }
                    else if(Integer.valueOf(gameTable.getCard2Hp()) != 0){
                        stringBuffer.append("切换至:" + characterTableMapper.selectByPrimaryKey(gameTable.getCharacterCard2()).getName());
                        gameTable.setNowCard(gameTable.getCharacterCard2());
                        break;
                    }
                    else if(Integer.valueOf(gameTable.getCard3Hp()) != 0){
                        stringBuffer.append("切换至:" + characterTableMapper.selectByPrimaryKey(gameTable.getCharacterCard3()).getName());
                        gameTable.setNowCard(gameTable.getCharacterCard3());
                        break;
                    }
                    //全员死亡
                    stringBuffer.append("全员死亡,游戏结束");
                    gameTable.setGameStatus(2);
                    break;
                case "user" : //玩家胜利
                    //获取经验值和抽取随机角色卡
                    gameTable.setGameStatus(2);
                    stringBuffer.append("敌方死亡");
                    //获取经验值,敌方等级 * 10

                    break;
            }
        }
        //更新游戏对局
        gameTableMapper.updateByPrimaryKeySelective(gameTable);
        System.out.println(stringBuffer);
        return JsonReturn.ok(stringBuffer);
    }

    //随机事件方法
    //70%概率获取资源，30概率遇见战斗
    public String ShiJian(){
        Random random = new Random();
        double randomValue = random.nextDouble() * 100;
        if(randomValue < 75){
            return "get";
        }
        else if(randomValue > 75){
            return "fight";
        }
        return null;
    }

    //血条绘制
    public String blood(Integer maxBlood , Integer nowBlood){
        String s = RPGgame.printHealthBar(nowBlood, maxBlood);
        return s;
    }
    /**
     * 攻击伤害计算
     * @param gameTable 对局对象
     * */
    public GameTable AttackDamage(GameTable gameTable){
        CharacterTable characterTable = characterTableMapper.selectByPrimaryKey(gameTable.getNowCard());
        EnemyTable enemyTable = enemyTableMapper.selectByPrimaryKey(gameTable.getEnemyId());

        characterToUserExample.clear();
        characterToUserExample.createCriteria().andQqIdEqualTo(gameTable.getQqId()).andCharacterIdEqualTo(gameTable.getNowCard());
        Integer lv = characterToUserMapper.selectByExample(characterToUserExample).get(0).getLv();
        Integer integer = CharacterAggressivity(Integer.valueOf(characterTable.getAggressivity()), lv);

        //伤害计算公式,原始攻击-敌方防御=最终伤害，敌我双方一致
        //玩家攻击敌方
        Integer Damage = Integer.valueOf(gameTable.getEnemyHp()) - (integer - Integer.valueOf(enemyTable.getDefensive()));//敌方剩余hp
        String EnemyHp = String.valueOf(Integer.valueOf(gameTable.getEnemyHp()) - Damage);//玩家造成的伤害
        gameTable.setDamage(Integer.valueOf(EnemyHp));
        gameTable.setEnemyHp(String.valueOf(Damage));

        if(Integer.valueOf(Damage) <= 0){
            //玩家攻击敌方，对面血量归0
            gameTable.setWinName("user");
            //不再继续执行直接返回
            gameTable.setEnemyHp(String.valueOf(0));
            return gameTable;
        }

        Integer Defensive = Integer.valueOf(characterTable.getDefensive());
        Defensive = CharacterDefensive(Defensive, lv);

        //判断当前上场角色是第几位
        if(gameTable.getCharacterCard1() == gameTable.getNowCard()){
            Integer sh = Integer.valueOf(enemyTable.getAggressivity()) - Defensive;
            if(sh <= 0){//如果攻击力小于防御力则造成等级 * 2的固定伤害
                sh = enemyTable.getLv() * 2;
            }
           //敌方攻击玩家
           Damage = Integer.valueOf(gameTable.getCard1Hp()) - (sh);//剩余血量
            gameTable.setEDamage(Integer.valueOf(gameTable.getCard1Hp()) - Damage);
            gameTable.setCard1Hp(String.valueOf(Damage));
            if(Integer.valueOf(Damage) <= 0){
                //敌方攻击玩家，血量归0
                gameTable.setWinName("enemy");
                gameTable.setCard1Hp(String.valueOf(0));
            }
           return gameTable;
        }
        if(gameTable.getCharacterCard2() == gameTable.getNowCard()){
            Integer sh = Integer.valueOf(enemyTable.getAggressivity()) - Defensive;
            if(sh < 0){//如果攻击力小于防御力则造成等级 * 2的固定伤害
                sh = enemyTable.getLv() * 2;
            }
            //敌方攻击玩家
            Damage = Integer.valueOf(gameTable.getCard2Hp()) - (sh);
            gameTable.setEDamage(Integer.valueOf(gameTable.getCard2Hp()) - Damage);
            gameTable.setCard2Hp(String.valueOf(Damage));
            if(Integer.valueOf(Damage) <= 0){
                //敌方攻击玩家，血量归0
                gameTable.setWinName("enemy");
                gameTable.setCard2Hp(String.valueOf(0));
            }
            return gameTable;
        }
        if(gameTable.getCharacterCard3() == gameTable.getNowCard()){
            Integer sh = Integer.valueOf(enemyTable.getAggressivity()) - Defensive;
            if(sh < 0){//如果攻击力小于防御力则造成等级 * 2的固定伤害
                sh = enemyTable.getLv() * 2;
            }
            Damage = Integer.valueOf(gameTable.getCard3Hp()) - (sh);
            gameTable.setEDamage(Integer.valueOf(gameTable.getCard3Hp()) - Damage);
            gameTable.setCard3Hp(String.valueOf(Damage));
            if(Integer.valueOf(Damage) <= 0){
                //敌方攻击玩家，血量归0
                gameTable.setWinName("enemy");
                gameTable.setCard3Hp(String.valueOf(0));
            }
            return gameTable;
        }
       return null;
    }
    /**
     * 等级追加属性计算 -- 血量
     * */
    public Integer CharacterBool(Integer hp , Integer lv){
        //每一级提高10点攻击力和20点生命值,20点防御力
        if(lv > 1){
            return hp + ((lv - 1) * 20);
        }
        return hp;
    }

    /**
     * 等级追加属性计算 -- 攻击力
     * */
    public Integer CharacterAggressivity(Integer Aggressivity , Integer lv){
        if(lv > 1){
            return Aggressivity + ( (lv - 1) * 10);
        }
        return Aggressivity;
    }

    /**
     * 等级追加属性计算 -- 防御力
     * */
    public Integer CharacterDefensive(Integer Defensive , Integer lv){
        if(lv > 1){
            return Defensive + ( (lv - 1) * 20);
        }
        return Defensive;
    }
}
